package com.mkyong.rest;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import com.mkyong.Track;
import com.mkyong.wowData;
import com.projectY.dao.DataDb;


@Path("/extension")
public class JSONService {

	@GET
	@Path("/get")
	@Produces(MediaType.APPLICATION_JSON)
	public Track getTrackInJSON() {

		Track track = new Track();
		track.setTitle("Enter Sandman");
		track.setSinger("Metallica");

		return track;

	}

	@POST
	@Path("/getLinkUpvotes")
	@Consumes(MediaType.APPLICATION_JSON)
	public Response createTrackInJSON(String track) throws JSONException, SQLException {
//		{"links":["http://www.cs.utexas.edu/users/djimenez/utsa/cs1723/lecture2.html",
//		          "http://dl.acm.org/citation.cfm?id=73040","http://en.wikipedia.org/wiki/Heap_(data_structure)",
//		          "http://en.wikipedia.org/wiki/Heap_(data_structure)"],"friends":["arushi","sumit","vrinda","ishu"],"site":"twitter"}
		System.out.println(track+" track");
		JSONObject obj=new JSONObject(track);
		JSONArray linksArray= obj.getJSONArray("links");
		ArrayList<String> links=new ArrayList<String>();
		for(int i=0;i<linksArray.length();i++)
		{
			links.add(linksArray.getString(i));
		}
		String site=obj.getString("site");
		JSONArray friendsArray= obj.getJSONArray("friends");
		ArrayList<String> friends=new ArrayList<String>();
		for(int i=0;i<friendsArray.length();i++)
		{
			friends.add(friendsArray.getString(i).toLowerCase());
		}
		System.out.println(links+" \n "+friends);
		JSONObject res=new JSONObject(new DataDb().readLinksProfile(links,friends));
		res.put("site", site);
		return Response.status(201).entity(res).build();
	}
	@POST
	@Path("/upVote")
	@Consumes(MediaType.APPLICATION_JSON)
	public Response upVote(String track) throws JSONException, SQLException {
//		{"link":"http://www.mkyong.com/jdbc/jdbc-sasa-example-insert-a-record","user":"ishu"}
		JSONObject obj=new JSONObject(track);
		System.out.println(track);
		int res= new DataDb().Vote(obj.getString("link"),obj.getString("user"),obj.getInt("vote"),obj.getString("query"),obj.getInt("tty"));
		System.out.println(res);
		JSONObject result = new JSONObject();


		if(res==-1)
		{
			result.put("result","alreadyThere");
		}
		else
		if(res==1)
		{
			result.put("result","success");
		}
		else
		{
			result.put("result","failure");
		}
		return Response.status(201).entity(result).build();
	}
	
	@POST
	@Path("/getWow")
	@Consumes(MediaType.APPLICATION_JSON)
	public Response getWow(String track) throws JSONException, SQLException {
//		{"link":"http://www.mkyong.com/jdbc/jdbc-sasa-example-insert-a-record","user":"ishu","site":"wow","query":"football"}
		System.out.println(track);
		JSONObject obj=new JSONObject(track);
		JSONArray linksArray= obj.getJSONArray("links");
		JSONArray friendsArray= obj.getJSONArray("friends");
		String query = obj.getString("query");
		//System.out.println("AKSHAY1 linksArray:" + linksArray);
		//System.out.println("AKSHAY2 friendsArray:" + friendsArray);
		//System.out.println("AKSHAY3 query:" + obj.getString("query"));
		
		ArrayList<String> links=new ArrayList<String>();
		for(int i=0;i<linksArray.length();i++)
		{
			links.add(linksArray.getString(i));
		}
		String site=obj.getString("site");

		ArrayList<String> friends=new ArrayList<String>();
		for(int i=0;i<friendsArray.length();i++)
		{
			friends.add(friendsArray.getString(i).toLowerCase());
		}
		//System.out.println("AKSHAY4: links+friends arraylist" + links + " \n " + friends);
		
		List<wowData> wd = new ArrayList<wowData>(new DataDb().getWowData(links,friends));
		wowData wo = new wowData();
		for(wowData iterator: wd) {
			System.out.println("AKSHAY7 " + iterator);
		}
		
		ArrayList<String> friends2 = new ArrayList<String>();
		List<wowData> wd2 = new ArrayList<wowData>(new DataDb().getWowData(links, friends2));
		for(wowData iterator: wd2) {
			System.out.println("AKSHAY8 " + iterator);
		}
		
		//for each link
			//step 1
			//call function by sending individual link {(String)linksArray.get(i)} and friends of particular website
		    //db query should get search query and minutes spent on that link
			//return number1
		
			//step 2
			//call function by sending individual link {(String)linksArray.get(i)} to get all results back
		    //db query should get search query and minutes spent on that link
		    //return number2
		
		    //r1 = (n1*2 + n2*1)/30
			//return r1+r2+r3/3
		
		//initialize wow factors in result hashmap to zero
		HashMap<String,Float> linksFriendsMap=new HashMap<String,Float>();
		for(int i=0;i<linksArray.length();i++)
		{
			linksFriendsMap.put((String)linksArray.get(i), (float)0.0);
		}
		
		HashMap<String,Float> linksMap=new HashMap<String,Float>();
		for(int i=0;i<linksArray.length();i++)
		{
			linksMap.put((String)linksArray.get(i), (float)0.0);
		}
		
		HashMap<String,Float> linksFriendsTotalTimeMap=new HashMap<String,Float>();
		for(int i=0;i<linksArray.length();i++)
		{
			linksFriendsTotalTimeMap.put((String)linksArray.get(i), (float)0.0);
		}
		
		HashMap<String,Float> linksTotalTimeMap=new HashMap<String,Float>();
		for(int i=0;i<linksArray.length();i++)
		{
			linksTotalTimeMap.put((String)linksArray.get(i), (float)0.0);
		}
		
		HashMap<String,Integer> res=new HashMap<String,Integer>();
		for(int i=0;i<linksArray.length();i++)
		{
			res.put((String)linksArray.get(i), 0);
		}

		calculateMaps(linksArray, query,  wd, linksFriendsMap, linksFriendsTotalTimeMap);
		calculateMaps(linksArray, query, wd2,        linksMap,        linksTotalTimeMap);
//		for(wowData iterator: wd) {
//			System.out.println("AKSHAY9 " + iterator);
//			//System.out.println("AKSHAY9 " + query);
//			float matchCount = 0;
//			//find number of words
//			String[] words = getWordsInQuery(iterator.getQuery());
//			for(int i =0;i<words.length;i++) {
//				if(query.contains(words[i])) {
//					matchCount++;
//				}
//				//System.out.println(words[i] + query.contains(words[i]));
//			}
//			String[] queryWords = getWordsInQuery(query);
//			//System.out.println("AKSHAY10: matchCount: " + matchCount);
//			float matchFactor = matchCount/(float)queryWords.length;
//			//System.out.println("AKSHAY10: matchfator: " + matchFactor);
//			float rowOutput = matchFactor * iterator.getTime();
//			System.out.println("AKSHAY11: rowOutput: " + rowOutput);
//			
//			if(iterator.getVote() == 1) {
//			//add to result
//				linksFriendsMap.put(iterator.getLink(), linksFriendsMap.get(iterator.getLink()) + rowOutput);
//			} else {
//			//subtract from result	
//				linksFriendsMap.put(iterator.getLink(), linksFriendsMap.get(iterator.getLink()) - rowOutput);
//			}
//			
//			linksFriendsTotalTimeMap.put(iterator.getLink(), linksFriendsTotalTimeMap.get(iterator.getLink()) + iterator.getTime());
//		}
//		
		for(int i=0;i<linksArray.length();i++)
		{
			System.out.println((String)linksArray.get(i) + " : " + linksFriendsMap.get((String)linksArray.get(i)));
		}
		
		for(int i=0;i<linksArray.length();i++)
		{
			System.out.println((String)linksArray.get(i) + " : " + linksFriendsTotalTimeMap.get((String)linksArray.get(i)));
		}

		for(int i=0;i<linksArray.length();i++)
		{
			System.out.println((String)linksArray.get(i) + " : " + linksMap.get((String)linksArray.get(i)));
		}
		
		for(int i=0;i<linksArray.length();i++)
		{
			System.out.println((String)linksArray.get(i) + " : " + linksTotalTimeMap.get((String)linksArray.get(i)));
		}
		
		for(int i=0;i<linksArray.length();i++)
		{
			int output = 0;
			int friendsToAllFactor = 2;
			
			float temp1 = (linksFriendsMap.get((String)linksArray.get(i))/linksFriendsTotalTimeMap.get((String)linksArray.get(i))) * friendsToAllFactor;
			float temp2 = (linksMap.get((String)linksArray.get(i))/linksTotalTimeMap.get((String)linksArray.get(i)));
			
			float temp3 = (temp1 + temp2)/3;
			output = (int)(temp3 * 100);
			res.put((String)linksArray.get(i), output);
		}
		
		
		JSONObject result = new JSONObject(res);
		Iterator it = res.entrySet().iterator();
		System.out.println("##############################################################################################################");
	    while (it.hasNext()) {
	        Map.Entry pairs = (Map.Entry)it.next();
	        System.out.println(pairs.getKey() + " = " + pairs.getValue());
	        it.remove(); // avoids a ConcurrentModificationException
	    }
	    System.out.println("--------------------------------------------------------------------------------------------------------------");
		result.put("site", site);
		return Response.status(201).entity(result).build();
	}
	
	public String[] getWordsInQuery(String query) {
		String[] words = query.split("\\s+");
		return words;
	}
	
	public void calculateMaps(JSONArray linksArray, String query, List<wowData> wd, HashMap<String,Float> linksFriendsMap, HashMap<String,Float> linksFriendsTotalTimeMap) throws JSONException {
		for(wowData iterator: wd) {
			System.out.println("AKSHAY9 " + iterator);
			//System.out.println("AKSHAY9 " + query);
			float matchCount = 0;
			//find number of words
			String[] words = getWordsInQuery(iterator.getQuery());
			for(int i =0;i<words.length;i++) {
				if(query.contains(words[i])) {
					matchCount++;
				}
				//System.out.println(words[i] + query.contains(words[i]));
			}
			String[] queryWords = getWordsInQuery(query);
			//System.out.println("AKSHAY10: matchCount: " + matchCount);
			float matchFactor = matchCount/(float)queryWords.length;
			//System.out.println("AKSHAY10: matchfator: " + matchFactor);
			float rowOutput = matchFactor * iterator.getTime();
			System.out.println("AKSHAY11: rowOutput: " + rowOutput);
			
			if(iterator.getVote() == 1) {
			//add to result
				linksFriendsMap.put(iterator.getLink(), linksFriendsMap.get(iterator.getLink()) + rowOutput);
			} else {
			//subtract from result	
				//linksFriendsMap.put(iterator.getLink(), linksFriendsMap.get(iterator.getLink()) - rowOutput);
			}
			
			linksFriendsTotalTimeMap.put(iterator.getLink(), linksFriendsTotalTimeMap.get(iterator.getLink()) + iterator.getTime());
		}
		
//		for(int i=0;i<linksArray.length();i++)
//		{
//			System.out.println((String)linksArray.get(i) + " : " + linksFriendsMap.get((String)linksArray.get(i)));
//		}
//		
//		for(int i=0;i<linksArray.length();i++)
//		{
//			System.out.println((String)linksArray.get(i) + " : " + linksFriendsTotalTimeMap.get((String)linksArray.get(i)));
//		}
	}
	
	@POST
	@Path("/storeTimeTaken")
	@Consumes(MediaType.APPLICATION_JSON)
	public Response storeTimeTaken(String track) throws JSONException, SQLException {
//		{"link":"http://www.mkyong.com/jdbc/jdbc-sasa-example-insert-a-record","user":"ishu"}
		track.replace("\\", " ");
		JSONObject obj=new JSONObject(track);
		System.out.println(track);
		int res= new DataDb().storeTimTaken(obj.getString("link"),obj.getString("twitter"),obj.getString("facebook"),obj.getString("gapi") ,obj.getInt("tty"));
		System.out.println(res);
		JSONObject result = new JSONObject();


		if(res==-1)
		{
			result.put("result","alreadyThere");
		}
		else
		if(res==1)
		{
			result.put("result","success");
		}
		else
		{
			result.put("result","failure");
		}
		return Response.status(201).entity(result).build();
	}
	@POST
	@Path("/downVote")
	@Consumes(MediaType.APPLICATION_JSON)
	public Response downVote(String track) throws JSONException, SQLException {
//		{"link":"http://www.mkyong.com/jdbc/jdbc-sasa-example-insert-a-record","user":"ishu"}
		JSONObject obj=new JSONObject(track);
		int res= new DataDb().downVote(obj.getString("link"),obj.getString("user"),obj.getInt("vote"),obj.getString("query"));
		System.out.println(res);
		JSONObject result = new JSONObject();


		if(res==-1)
		{
			result.put("result","alreadyThere");
		}
		else
		if(res==1)
		{
			result.put("result","success");
		}
		else
		{
			result.put("result","failure");
		}
		return Response.status(201).entity(result).build();
	}
	@POST
	@Path("/upVotingFriends")
	@Consumes(MediaType.APPLICATION_JSON)
	public Response upVotingFriends(String track) throws JSONException, SQLException {
//		{"link":"http://www.mkyong.com/jdbc/jdbc-sasa-example-insert-a-record","friends":["ishu","arushi"]}
		JSONObject obj=new JSONObject(track);
		JSONArray friendsArray= obj.getJSONArray("friends");
		ArrayList<String> friends=new ArrayList<String>();
		for(int i=0;i<friendsArray.length();i++)
		{
			friends.add(friendsArray.getString(i));
		}
		JSONArray res=new JSONArray(new DataDb().upVotingFriends(obj.getString("link"),friends));
		System.out.println(res);
		return Response.status(201).entity(res).build();
	}
	
	@POST
	@Path("/isVoted")
	@Consumes(MediaType.APPLICATION_JSON)
	public Response isVoted(String track) throws JSONException, SQLException {
//		{"link":"http://www.mkyong.com/jdbc/jdbc-sasa-example-insert-a-record","friends":["ishu","arushi"]}
		JSONObject obj=new JSONObject(track);
		JSONObject res=new JSONObject( );
		System.out.println(obj.getString("user") +" "+obj.getString("link") );
		res.put("result", new DataDb().checkIfUpVoted(obj.getString("link"),obj.getString("user"))?1:-1 );
		return Response.status(201).entity(res).build();
	}
}